<!-- 分类管理页面 - 提供分类的增删改查功能，支持树形结构 -->
<template>
    <div class="category-list">
        <!-- 示例数据提示 -->
        <el-alert v-if="isUsingSampleData" title="正在使用示例数据" description="后端API调用失败，当前显示的是示例数据。请检查网络连接或联系管理员。"
            type="warning" :closable="false" show-icon class="sample-data-notice" />

        <!-- 操作区域 - 包含页面标题和新增按钮 -->
        <div class="action-section">
            <div class="section-header">
                <h2>分类管理</h2>
                <div class="header-actions">
                    <!-- 搜索框 -->
                    <div class="search-box">
                        <el-input v-model="searchKeyword" placeholder="搜索分类名称..." clearable @input="handleSearch">
                            <template #prefix>
                                <el-icon>
                                    <Search />
                                </el-icon>
                            </template>
                        </el-input>
                    </div>
                    <el-button type="primary" @click="showAddDialog">
                        <el-icon>
                            <Plus />
                        </el-icon>
                        新增分类
                    </el-button>
                </div>
            </div>
        </div>

        <!-- 分类列表表格区域 -->
        <div class="table-section">
            <!-- 使用Element Plus表格组件，支持树形数据展示 -->
            <el-table :data="categories" v-loading="loading" style="width: 100%" row-key="id"
                :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
                <!-- 分类名称列 -->
                <el-table-column prop="name" label="分类名称" min-width="200">
                    <template #default="{ row }">
                        <div class="category-name">
                            <span class="name-text">{{ row.name }}</span>
                            <!-- 默认分类标识 -->
                            <el-tag v-if="row.isDefault" size="small" type="success">默认</el-tag>
                        </div>
                    </template>
                </el-table-column>

                <!-- 分类描述列 -->
                <el-table-column prop="description" label="描述" min-width="300" />

                <!-- 文章数量列 -->
                <el-table-column prop="postCount" label="文章数量" width="120">
                    <template #default="{ row }">
                        <el-tag size="small" type="info" class="count-tag">{{ row.postCount }}</el-tag>
                    </template>
                </el-table-column>

                <!-- 排序列 -->
                <el-table-column prop="sort" label="排序" width="100">
                    <template #default="{ row }">
                        <span class="sort-number">{{ row.sort }}</span>
                    </template>
                </el-table-column>

                <!-- 创建时间列 -->
                <el-table-column prop="createTime" label="创建时间" width="180">
                    <template #default="{ row }">
                        {{ formatDate(row.createTime) }}
                    </template>
                </el-table-column>

                <!-- 操作列 - 固定在右侧 -->
                <el-table-column label="操作" width="280" fixed="right">
                    <template #default="{ row }">
                        <div class="action-buttons">
                            <!-- 编辑按钮 -->
                            <el-button size="small" type="primary" plain @click="editCategory(row)" class="action-btn">
                                <el-icon>
                                    <Edit />
                                </el-icon>
                                编辑
                            </el-button>
                            <!-- 查看文章按钮 -->
                            <el-button size="small" type="success" plain @click="viewPosts(row.id)" class="action-btn">
                                <el-icon>
                                    <View />
                                </el-icon>
                                查看文章
                            </el-button>
                            <!-- 更多操作下拉菜单 -->
                            <el-dropdown @command="handleCommand" trigger="click">
                                <el-button size="small" type="info" plain class="action-btn more-btn">
                                    <el-icon>
                                        <MoreFilled />
                                    </el-icon>
                                    更多
                                    <el-icon class="el-icon--right">
                                        <ArrowDown />
                                    </el-icon>
                                </el-button>
                                <template #dropdown>
                                    <el-dropdown-menu>
                                        <!-- 上移选项 -->
                                        <el-dropdown-item :command="{ action: 'moveUp', id: row.id }">
                                            <el-icon>
                                                <ArrowUp />
                                            </el-icon>
                                            上移
                                        </el-dropdown-item>
                                        <!-- 下移选项 -->
                                        <el-dropdown-item :command="{ action: 'moveDown', id: row.id }">
                                            <el-icon>
                                                <ArrowDown />
                                            </el-icon>
                                            下移
                                        </el-dropdown-item>
                                        <!-- 删除选项 -->
                                        <el-dropdown-item divided :command="{ action: 'delete', id: row.id }">
                                            <el-icon>
                                                <Delete />
                                            </el-icon>
                                            删除
                                        </el-dropdown-item>
                                    </el-dropdown-menu>
                                </template>
                            </el-dropdown>
                        </div>
                    </template>
                </el-table-column>
            </el-table>
        </div>

        <!-- 新增/编辑分类对话框 -->
        <el-dialog v-model="dialogVisible" :title="isEdit ? '编辑分类' : '新增分类'" width="500px" @close="resetForm">
            <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
                <!-- 分类名称输入框 -->
                <el-form-item label="分类名称" prop="name">
                    <el-input v-model="form.name" placeholder="请输入分类名称" />
                </el-form-item>

                <!-- 父分类选择器 -->
                <el-form-item label="父分类" prop="parentId">
                    <el-select v-model="form.parentId" placeholder="请选择父分类" clearable>
                        <el-option v-for="category in parentCategories" :key="category.id" :label="category.name"
                            :value="category.id" />
                    </el-select>
                </el-form-item>

                <!-- 分类描述输入框 -->
                <el-form-item label="描述" prop="description">
                    <el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入分类描述" />
                </el-form-item>

                <!-- 排序值输入框 -->
                <el-form-item label="排序" prop="sort">
                    <el-input-number v-model="form.sort" :min="0" :max="999" />
                </el-form-item>
            </el-form>

            <!-- 对话框底部按钮 -->
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="submitForm" :loading="submitting">
                        {{ isEdit ? '更新' : '创建' }}
                    </el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
// 导入Vue 3 Composition API核心功能
import { ref, computed, onMounted } from 'vue'
// 导入Vue Router用于页面导航
import { useRouter } from 'vue-router'
// 导入Element Plus组件和消息提示
import { ElMessage, ElMessageBox } from 'element-plus'
// 导入Element Plus图标组件
import { Plus, ArrowDown, Edit, View, MoreFilled, ArrowUp, Delete, Loading, Search } from '@element-plus/icons-vue'
// 导入Element Plus表单类型
import type { FormInstance, FormRules } from 'element-plus'
// 导入API工具函数
import { get, post, put, del, API_PATHS } from '@/utils/api'

// 获取路由实例，用于页面跳转
const router = useRouter()

// 响应式数据定义
const loading = ref(false) // 表格加载状态
const dialogVisible = ref(false) // 对话框显示状态
const isEdit = ref(false) // 是否为编辑模式
const submitting = ref(false) // 表单提交状态
const formRef = ref<FormInstance>() // 表单引用
const isUsingSampleData = ref(false) // 是否使用示例数据
const isLoading = ref(false) // 数据加载状态
const searchKeyword = ref('') // 搜索关键词
const allCategories = ref<Category[]>([]) // 存储所有分类数据
const categories = ref<Category[]>([]) // 当前显示的分类数据

// 类型定义
interface Category {
    id: number
    name: string
    description: string
    parentId?: number
    postCount: number
    sort: number
    createTime: string
    isDefault: boolean
    children?: Category[]
}

interface CategoryRequest {
    name: string
    description: string
    parentId?: number
    sort: number
}

interface CategoryResponse {
    id: number
    name: string
    description: string
    parentId?: number
    postCount: number
    sort: number
    createTime: string
    isDefault: boolean
    children?: CategoryResponse[]
}

interface MoveCategoryRequest {
    direction: 'up' | 'down'
}

// 示例数据
const sampleCategories: Category[] = [
    {
        id: 1,
        name: '前端开发',
        description: '前端技术相关文章',
        parentId: undefined,
        postCount: 15,
        sort: 1,
        createTime: '2024-12-01T10:00:00Z',
        isDefault: false,
        children: [
            {
                id: 4,
                name: 'Vue.js',
                description: 'Vue.js 相关技术',
                parentId: 1,
                postCount: 8,
                sort: 1,
                createTime: '2024-12-05T14:30:00Z',
                isDefault: false
            },
            {
                id: 5,
                name: 'React',
                description: 'React 相关技术',
                parentId: 1,
                postCount: 7,
                sort: 2,
                createTime: '2024-12-06T09:15:00Z',
                isDefault: false
            }
        ]
    },
    {
        id: 2,
        name: '后端开发',
        description: '后端技术相关文章',
        parentId: undefined,
        postCount: 12,
        sort: 2,
        createTime: '2024-12-02T11:00:00Z',
        isDefault: false
    },
    {
        id: 3,
        name: '编程语言',
        description: '各种编程语言相关文章',
        parentId: undefined,
        postCount: 8,
        sort: 3,
        createTime: '2024-12-03T15:00:00Z',
        isDefault: false
    }
]

// 使用示例数据的函数
const useSampleData = () => {
    allCategories.value = sampleCategories
    categories.value = [...sampleCategories]
    isUsingSampleData.value = true
    ElMessage.warning('正在使用示例数据，后端API调用失败')
}

// 表单数据对象
const form = ref<CategoryRequest>({
    name: '', // 分类名称
    description: '', // 分类描述
    parentId: undefined, // 父分类ID
    sort: 0 // 排序值
})

// 当前编辑的分类ID
const currentEditId = ref<number>(0)

// 表单验证规则配置
const rules: FormRules = {
    name: [
        { required: true, message: '请输入分类名称', trigger: 'blur' },
        { min: 2, max: 20, message: '分类名称长度在 2 到 20 个字符', trigger: 'blur' }
    ],
    description: [
        { max: 200, message: '描述长度不能超过 200 个字符', trigger: 'blur' }
    ],
    sort: [
        { required: true, message: '请输入排序值', trigger: 'blur' }
    ]
}

// 分类数据 - 支持树形结构（已在上面声明）

// 计算属性 - 过滤出可选的父分类（排除当前编辑的分类）
const parentCategories = computed(() => {
    return categories.value.filter(category => category.id !== currentEditId.value)
})

// API调用函数

/**
 * 获取分类列表
 * 从API获取所有分类信息，支持树形结构
 */
const fetchCategories = async () => {
    loading.value = true
    try {
        const response = await get<CategoryResponse[]>(API_PATHS.CATEGORY.TREE, {
            timeout: 8000,
            retry: 2
        })

        if (response && response.success && response.data) {
            allCategories.value = response.data
            categories.value = [...response.data]
            isUsingSampleData.value = false
        } else {
            throw new Error('获取分类列表失败')
        }
    } catch (error) {
        console.error('获取分类列表失败:', error)
        useSampleData()
    } finally {
        loading.value = false
    }
}

/**
 * 创建分类
 * @param categoryData - 分类数据
 */
const createCategory = async (categoryData: CategoryRequest) => {
    try {
        const response = await post<CategoryResponse>(API_PATHS.CATEGORY.CREATE, categoryData, {
            timeout: 8000,
            retry: 2
        })

        if (response && response.success && response.data) {
            ElMessage.success('分类创建成功')
            await fetchCategories() // 重新获取分类列表
            return true
        } else {
            throw new Error('创建分类失败')
        }
    } catch (error) {
        console.error('创建分类失败:', error)
        ElMessage.error('创建分类失败，请重试')
        return false
    }
}

/**
 * 更新分类
 * @param id - 分类ID
 * @param categoryData - 分类数据
 */
const updateCategory = async (id: number, categoryData: CategoryRequest) => {
    try {
        const response = await put<CategoryResponse>(API_PATHS.CATEGORY.UPDATE(id.toString()), categoryData, {
            timeout: 8000,
            retry: 2
        })

        if (response && response.success && response.data) {
            ElMessage.success('分类更新成功')
            await fetchCategories() // 重新获取分类列表
            return true
        } else {
            throw new Error('更新分类失败')
        }
    } catch (error) {
        console.error('更新分类失败:', error)
        ElMessage.error('更新分类失败，请重试')
        return false
    }
}

/**
 * 删除分类
 * @param id - 分类ID
 */
const deleteCategoryAPI = async (id: number) => {
    try {
        const response = await del(API_PATHS.CATEGORY.DELETE(id.toString()), {
            timeout: 8000,
            retry: 2
        })

        if (response && response.success) {
            ElMessage.success('分类删除成功')
            await fetchCategories() // 重新获取分类列表
            return true
        } else {
            throw new Error('删除分类失败')
        }
    } catch (error) {
        console.error('删除分类失败:', error)
        ElMessage.error('删除分类失败，请重试')
        return false
    }
}

/**
 * 移动分类位置
 * @param id - 分类ID
 * @param direction - 移动方向
 */
const moveCategoryAPI = async (id: number, direction: 'up' | 'down') => {
    try {
        const response = await post(API_PATHS.CATEGORY.MOVE(id.toString()), { direction }, {
            timeout: 8000,
            retry: 2
        })

        if (response && response.success) {
            ElMessage.success('移动成功')
            await fetchCategories() // 重新获取分类列表
            return true
        } else {
            throw new Error('移动分类失败')
        }
    } catch (error) {
        console.error('移动分类失败:', error)
        ElMessage.error('移动分类失败，请重试')
        return false
    }
}

// 方法定义

/**
 * 显示新增分类对话框
 * 重置表单并设置为新增模式
 */
const showAddDialog = () => {
    isEdit.value = false
    dialogVisible.value = true
}

/**
 * 编辑分类
 * 将分类数据填充到表单中并设置为编辑模式
 * @param category - 要编辑的分类对象
 */
const editCategory = (category: Category) => {
    isEdit.value = true
    currentEditId.value = category.id
    form.value = {
        name: category.name,
        description: category.description,
        parentId: category.parentId,
        sort: category.sort
    }
    dialogVisible.value = true
}

/**
 * 查看分类下的文章
 * 跳转到文章列表页面并筛选该分类的文章
 * @param categoryId - 分类ID
 */
const viewPosts = (categoryId: number) => {
    router.push(`/admin/posts?category=${categoryId}`)
}

/**
 * 处理下拉菜单命令
 * 根据命令类型执行相应的操作
 * @param command - 命令对象，包含action和id
 */
const handleCommand = async (command: { action: string; id: number }) => {
    switch (command.action) {
        case 'moveUp':
            await moveCategory(command.id, 'up')
            break
        case 'moveDown':
            await moveCategory(command.id, 'down')
            break
        case 'delete':
            await deleteCategory(command.id)
            break
    }
}

/**
 * 移动分类位置
 * 调整分类的排序顺序
 * @param id - 分类ID
 * @param direction - 移动方向：'up' 或 'down'
 */
const moveCategory = async (id: number, direction: 'up' | 'down') => {
    await moveCategoryAPI(id, direction)
}

/**
 * 删除分类
 * 删除前会显示确认对话框
 * @param id - 要删除的分类ID
 */
const deleteCategory = async (id: number) => {
    try {
        await ElMessageBox.confirm('确定要删除这个分类吗？删除后该分类下的文章将变为未分类状态。', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        })

        await deleteCategoryAPI(id)
    } catch (error) {
        if (error !== 'cancel') {
            ElMessage.error('删除失败')
        }
    }
}

/**
 * 提交表单
 * 根据是否为编辑模式执行创建或更新操作
 */
const submitForm = async () => {
    if (!formRef.value) return

    try {
        // 验证表单数据
        await formRef.value.validate()
        submitting.value = true

        let success = false
        if (isEdit.value) {
            success = await updateCategory(currentEditId.value, form.value)
        } else {
            success = await createCategory(form.value)
        }

        if (success) {
            dialogVisible.value = false
        }
    } catch (error) {
        ElMessage.error('操作失败')
    } finally {
        submitting.value = false
    }
}

/**
 * 重置表单
 * 清空表单数据并重置验证状态
 */
const resetForm = () => {
    if (formRef.value) {
        formRef.value.resetFields()
    }
    form.value = {
        name: '',
        description: '',
        parentId: undefined,
        sort: 0
    }
}

/**
 * 格式化日期显示
 * @param dateString - ISO格式的日期字符串
 * @returns 格式化后的本地日期字符串
 */
const formatDate = (dateString: string) => {
    const date = new Date(dateString)
    return date.toLocaleDateString('zh-CN')
}

/**
 * 获取分类列表数据
 * 从API获取所有分类信息
 */
const fetchCategoriesData = async () => {
    await fetchCategories()
}

/**
 * 处理搜索输入
 * 调用API搜索分类，如果失败则使用前端过滤作为降级
 */
const handleSearch = async () => {
    if (searchKeyword.value.trim()) {
        try {
            // 调用API搜索分类
            const searchUrl = `${API_PATHS.CATEGORY.SEARCH}?keyword=${encodeURIComponent(searchKeyword.value)}`
            const response = await get(searchUrl, {
                timeout: 8000,
                retry: 2
            })

            if (response && response.success && response.data) {
                // API搜索成功，更新分类列表
                categories.value = response.data
            } else {
                // API搜索失败，使用前端过滤作为降级
                categories.value = allCategories.value.filter(category =>
                    category.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
                )
            }
        } catch (error) {
            console.error('搜索分类失败，使用前端过滤:', error)
            // API调用失败，使用前端过滤作为降级
            categories.value = allCategories.value.filter(category =>
                category.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
            )
        }
    } else {
        // 如果没有搜索关键词，显示所有分类
        categories.value = [...allCategories.value]
    }
}

// 组件挂载时获取初始数据
onMounted(() => {
    fetchCategoriesData()
})
</script>

<style scoped lang="scss">
// 导入分类管理页面样式
@use '../../assets/styles/admin/_categories';
</style>